%% Author : lichuang
-module(echubby_quorum_connector).

-behaviour(gen_server).
-include("echubby.hrl").
-include("quorum_peer_pb.hrl").
-export([start_link/1]).
-export([init/1,
	 handle_call/3,
	 handle_cast/2,
	 handle_info/2,
	 terminate/2,
	 code_change/3]).

-record(connect_state, {socket, status}).
start_link(Id) ->
  gen_server:start_link({local, ?MODULE}, ?MODULE, [Id], []).

init([Id]) ->
  ?INFO_MSG("spawn process ~p to connect other quorum server ~p",
    [self(), Id]),
  {ok, {#connect_state{status = unconnected}}}.

handle_cast({connect_to_server, ServerInfo}, _State) ->
  {ok, Socket} = connect_to_server(ServerInfo),
  {noreply, #connect_state{socket = Socket, status = connected}};
handle_cast(#notification{leader = Leader,
			  gxid   = Gxid,
			  epoch  = Epoch,
			  state	 = State,
			  server_id = ServerId},
	    #connect_state{socket = Socket,
			   status = Status}) ->
 case Status of
   unconnected ->
    ?INFO_MSG("receive msg ~p", [ServerId]);
  connected ->
    ?INFO_MSG("receive msg ~p", [ServerId])
 end,
 ?INFO_MSG("receive msg ~p", [ServerId]),
 {noreply, #connect_state{socket = Socket, status = Status}};
handle_cast(_Req, State) ->
  {noreply, State}.

handle_call(_Req, _From, State) ->
  {noreply, State}.

handle_info(_Info, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
  ok.

code_change(_OldVsn, State, _Extra) ->
  {ok, State}.

connect_to_server(ServerInfo) ->
  {_, Host, Port} = ServerInfo,
  case gen_tcp:connect(Host, Port,
		       [binary, {packet, 4}]) of
    {ok, Socket} ->
      ?INFO_MSG("connect to [~p:~p] success", [Host, Port]),
      {ok, Socket};
    {error, Reason} ->
      ?INFO_MSG("connect to [~p:~p] fail: ~p", [Host, Port, Reason]),
      timer:sleep(5000),
      ?INFO_MSG("now try to connect [~p:~p] again", [Host, Port]),
      connect_to_server(ServerInfo)
  end.
